package com.stark.commons.lang.enums;

import lombok.Getter;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 枚举媒体类型。
 * @author Ben
 * @since 1.0.0
 * @version 1.0.0
 */
@Getter
public enum MediaType {
	
	APPLICATION_EXE("application/x-msdownload", "exe"),
	
	APPLICATION_JSON("application/json", "json"),
	
	APPLICATION_OCTET_STREAM("application/octet-stream"),
	
	APPLICATION_PDF("application/pdf", "pdf"),
	
	APPLICATION_RAR("application/x-rar", "rar"),
	
	APPLICATION_RPM("application/x-rpm", "rpm"),
	
	APPLICATION_TAR("application/x-tar", "tar"),
	
	APPLICATION_TAR_GZ("application/x-gzip", "tar.gz"),
	
	APPLICATION_ZIP("application/zip", "zip"),
	
	APPLICATION_7Z("application/x-7z-compressed", "7z"),
	
	AUDIO_WAV("audio/x-wav", "wav"),
	
	AUDIO_WMA("audio/x-ms-wma", "wma"),
	
	AUDIO_MP3("audio/mp3", "mp3"),
	
	IMAGE_BMP("image/bmp", "bmp"),

	IMAGE_GIF("image/gif", "gif"),
	
	IMAGE_ICON("image/x-icon", "ico"),
	
	IMAGE_JPEG("image/jpeg", "jpeg", "jpg", "jpe"),
	
	IMAGE_PNG("image/png", "png"),

	IMAGE_PSD("image/vnd.adobe.photoshop", "psd"),

	IMAGE_SVG("image/svg+xml", "svg"),
	
	IMAGE_TIFF("image/tiff", "tiff", "tif"),

	IMAGE_WEBP("image/webp", "webp"),
	
	OFFICE_DOC("application/msword", "doc"),
	
	OFFICE_DOCX("application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx"),
	
	OFFICE_XLS("application/vnd.ms-excel", "xls"),
	
	OFFICE_XLSX("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx"),
	
	OFFICE_PPT("application/vnd.ms-powerpoint", "ppt"),
	
	OFFICE_PPTX("application/vnd.openxmlformats-officedocument.presentationml.presentation", "pptx"),

	OFFICE_RTF("application/rtf", "rtf"),
	
	TEXT_HTML("text/html", "html", "htm"),
	
	TEXT_MARKDOWN("text/markdown", "md"),
	
	TEXT_PLAIN("text/plain", "txt"),
	
	TEXT_XML("text/xml", "xml"),
	
	VIDEO_AVI("video/avi", "avi"),
	
	VIDEO_FLV("video/x-flv", "flv"),
	
	VIDEO_MKV("video/x-matroska", "mkv"),
	
	VIDEO_MOV("video/quicktime", "mov"),
	
	VIDEO_MP4("video/mpeg4", "mp4"),
	
	VIDEO_WMV("video/x-ms-wmv", "wmv"),
	
	VIDEO_3GP("video/3gpp", "3gp");
	
	private final String contentType;
	
	private final String[] extensions;
	
	MediaType(String contentType, String... extensions) {
		this.contentType = contentType;
		this.extensions = extensions;
	}
	
	/**
	 * 获取媒体类型。
	 * @param contentType 内容类型。
	 * @return 存在时返回对象，否则返回 {@literal null} 。
	 */
	public static MediaType getByContentType(String contentType) {
		if (StringUtils.isBlank(contentType)) {
			return null;
		}
		
		for (MediaType mediaType : MediaType.values()) {
			if (mediaType.getContentType().equals(contentType)) {
				return mediaType;
			}
		}
		return null;
	}
	
	/**
	 * 根据扩展名获取媒体类型。
	 * @param extension 扩展名。
	 * @return 存在时返回对象，否则返回 {@literal null} 。
	 */
	public static MediaType getByExtension(String extension) {
		if (StringUtils.isBlank(extension)) {
			return null;
		}
		
		if (extension.startsWith(".") && extension.length() > 1) {
			extension = extension.substring(1);
		}
		extension = extension.toLowerCase();
		
		for (MediaType mediaType : MediaType.values()) {
			if (ArrayUtils.contains(mediaType.getExtensions(), extension)) {
				return mediaType;
			}
		}
		return null;
	}
	
	/**
	 * 获取音频类型。
	 * @return 音频类型。
	 */
	public static MediaType[] audios() {
		return nameStartWith("AUDIO_");
	}
	
	/**
	 * 获取图片类型。
	 * @return 图片类型。
	 */
	public static MediaType[] images() {
		return nameStartWith("IMAGE_");
	}
	
	/**
	 * 获取 WORD 类型。
	 * @return WORD 类型。
	 */
	public static MediaType[] officeWords() {
		return nameStartWith("OFFICE_DOC");
	}
	
	/**
	 * 获取 EXCEL 类型。
	 * @return WORD 类型。
	 */
	public static MediaType[] officeExcels() {
		return nameStartWith("OFFICE_XLS");
	}
	
	/**
	 * 获取 PPT 类型。
	 * @return PPT 类型。
	 */
	public static MediaType[] officePpts() {
		return nameStartWith("OFFICE_PPT");
	}
	
	/**
	 * 获取视频类型。
	 * @return 视频类型。
	 */
	public static MediaType[] videos() {
		return nameStartWith("VIDEO_");
	}
	
	private static MediaType[] nameStartWith(String prefix) {
		List<MediaType> list = new ArrayList<>();
		for (MediaType mediaType : MediaType.values()) {
			if (mediaType.name().startsWith(prefix)) {
				list.add(mediaType);
			}
		}
		return list.toArray(new MediaType[0]);
	}
	
}
